﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using CdcSoftware.Pivotal.Applications.Core.Client;
using CdcSoftware.Pivotal.Engine;
using CdcSoftware.Pivotal.Engine.Client.ClientTasks.Attributes;
using CdcSoftware.Pivotal.Engine.Client.Services.Interfaces;
using CdcSoftware.Pivotal.Engine.UI.Forms;
using CdcSoftware.Pivotal.Applications.Core.Common;
using Pcm.Retail.Client.FormTasks;
using CdcSoftware.Pivotal.Engine.Types.Database;
using CdcSoftware.Pivotal.Engine.Types.MailMerges;
using CdcSoftware.Pivotal.Engine.Types.DataTemplates;

namespace Pcm.Retail.Client.FormTasks.CommandHandlers
{
    public class RE_Cashier_Log : CommandClientTask
    {
        private bool changePassword = false;
        private bool clockOut = false;
        private Form popupAuthorization = null;
        private Form popupChangePassword = null;
        private DataRow[] loggedInCashier = null;        

        private System.Windows.Forms.TextBox txtCurrentPassword, txtNewPassword, txtConfirmPassword;
        private System.Windows.Forms.Button btnOk, btnCancel;
        private System.Windows.Forms.Label lblCurrentPassword,lblNewPassword, lblConfirmPassword;

        /// <summary>
        /// On click of Cashier Login/Logout item.
        /// </summary>
        /// <history>
        /// Revision   Date        Author  Description
        /// 6.0.12.1   19/04/2013  DS      Initial Version
        /// </history>
        [ClientTaskCommand]
        public virtual void CashierLoginCommand()
        {
            try
            {
                //DS: 19042013 - For Offline if the POS is not master POS, then don't allow to login.
                if (SystemClient.SystemInformation.IsMobile && !Globals.IsMasterPOS)
                    PivotalMessageBox.Show("This feature is not available Offline when POS is not Master POS.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else
                    Globals.NewForm("RE_Cashier_Log", null);
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }


        /// <summary>
        /// Logout when the subject is clicked.
        /// </summary>
        [ClientTaskCommand]
        public virtual void LogOut()
        {
            try
            {
                //DS: 19042013 - For Offline if the POS is not master POS, then don't allow to logout.
                if (SystemClient.SystemInformation.IsMobile && !Globals.IsMasterPOS)
                    PivotalMessageBox.Show("This feature is not available Offline when POS is not Master POS.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                else
                {
                    clockOut = true;
                    DataTable cashierLogin = Globals.GetDataTable("RE_Cashier Log for Today for Current POS", null, new string[] { "Staff_Id", "Staff_Code", 
                    "End_Time", "Store_Id", "POS_Id","Batch_Id" });
                    loggedInCashier = cashierLogin.AsEnumerable().Where(a => Convert.IsDBNull(a["End_Time"])).ToArray();

                    if (loggedInCashier.Count() == 1)
                    {
                        if (TypeConvert.ToBoolean(Globals.ServerSqlIndex("RE_Staff", "Prompt_To_Reset", Id.Create(loggedInCashier[0]["Staff_Id"]))))
                            ShowChangePasswordPopup();
                        else
                            ShowAuthorizationPopup();

                        ICenterContentView centerContentView = ClientContext.ClientAPIService.GetActiveContentObject() as ICenterContentView;
                        if (centerContentView is IFormView && this.FormView.FormName == "RE_Sale – Walk In")
                            this.FormView.CloseForm(true);
                    }
                    else if (loggedInCashier.Count() > 1)
                        PivotalMessageBox.Show("Multiple entry exists for the user." + Environment.NewLine +
                            "Please contact system Administrator.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    else
                        PivotalMessageBox.Show("No entry for the user to clock-out.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception exc)
            {
                Globals.HandleException(exc);
            }
        }

        /// <summary>
        /// Shows the Authorization Prompt.
        /// </summary>
        private void ShowAuthorizationPopup()
        {
            changePassword = false;
            popupAuthorization = new Form();

            this.txtCurrentPassword = new System.Windows.Forms.TextBox();
            this.btnOk = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.lblCurrentPassword = new System.Windows.Forms.Label();
            popupAuthorization.SuspendLayout();
            // 
            // txtCurrentPassword
            // 
            this.txtCurrentPassword.Location = new System.Drawing.Point(181, 30);
            this.txtCurrentPassword.Name = "txtCurrentPassword";
            this.txtCurrentPassword.Size = new System.Drawing.Size(109, 20);
            this.txtCurrentPassword.TabIndex = 1;
            this.txtCurrentPassword.UseSystemPasswordChar = true;            
            // 
            // btnOk
            // 
            this.btnOk.Location = new System.Drawing.Point(134, 80);
            this.btnOk.Name = "Ok";
            this.btnOk.Size = new System.Drawing.Size(75, 23);
            this.btnOk.TabIndex = 2;
            this.btnOk.Text = "Ok";
            this.btnOk.UseVisualStyleBackColor = true;
            this.btnOk.Click += new System.EventHandler(this.Ok_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.Location = new System.Drawing.Point(215, 80);
            this.btnCancel.Name = "Cancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 23);
            this.btnCancel.TabIndex = 3;
            this.btnCancel.Text = "Cancel";
            this.btnCancel.UseVisualStyleBackColor = true;
            // 
            // lblCurrentPassword
            // 
            this.lblCurrentPassword.AutoSize = true;
            this.lblCurrentPassword.Location = new System.Drawing.Point(43, 33);
            this.lblCurrentPassword.Name = "lblCurrentPassword";
            this.lblCurrentPassword.Size = new System.Drawing.Size(138, 15);
            this.lblCurrentPassword.TabIndex = 5;
            this.lblCurrentPassword.Text = "Password:";            
            // 
            // Form1
            // 
            popupAuthorization.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            popupAuthorization.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            popupAuthorization.AcceptButton = this.btnOk;
            popupAuthorization.CancelButton = this.btnCancel;
            popupAuthorization.ClientSize = new System.Drawing.Size(348, 133);
            popupAuthorization.StartPosition = FormStartPosition.CenterScreen;
            popupAuthorization.Controls.Add(this.lblCurrentPassword);
            popupAuthorization.Controls.Add(this.btnOk);
            popupAuthorization.Controls.Add(this.btnCancel);
            popupAuthorization.Controls.Add(this.txtCurrentPassword);
            popupAuthorization.Name = "popupAuthorization";
            popupAuthorization.Text = "Enter Password";
            popupAuthorization.ResumeLayout(false);
            popupAuthorization.PerformLayout();
            popupAuthorization.ShowDialog();
        }

        /// <summary>
        /// Event handler for the OK click of the popup pwd challenge.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.8.1        2011-09-06      DS              Initial version for Retail.                                                
        /// </history>
        private void Ok_Click(object sender, EventArgs e)
        {
            try
            {
                if (changePassword)
                {
                    //Verify the current password is correct and the new password matches the confirm password fields.
                    //Update the new password in the staff table and clear the Prompt_To_Change field and Clock-In the staff.

                    //User selects OK but value not provided.
                    if (txtCurrentPassword.Text.Trim() == string.Empty || txtNewPassword.Text.Trim() == string.Empty || txtConfirmPassword.Text.Trim() == string.Empty)
                    {
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtNewPassword.Text = string.Empty;
                        this.txtConfirmPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }

                    string password = TypeConvert.ToString(Globals.ServerSqlIndex("RE_Staff", "Password_", Id.Create(loggedInCashier[0]["Staff_Id"])));
                    //Match the old password with the DB value. If matched go ahead, esle prompt the user.
                    if (String.Equals(Globals.Decrypt(password), txtCurrentPassword.Text))
                    {
                        //If new password and the confirm password does not match prompt the user with error.
                        if (!String.Equals(txtNewPassword.Text, txtConfirmPassword.Text))
                        {
                            PivotalMessageBox.Show("Password confirmation failed. Please enter again.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            this.txtNewPassword.Text = string.Empty;
                            this.txtConfirmPassword.Text = string.Empty;
                            this.txtNewPassword.Focus();
                            return;
                        }

                        //Now change the password for the Staff and set the field Prompt_To_Reset to false.
                        this.SystemClient.ExecuteServerTask("RE_Store", "SetStaffPassword", new Type[] { typeof(Id), typeof(string) },
                            new object[] { Id.Create(loggedInCashier[0]["Staff_Id"]), Globals.Encrypt(this.txtNewPassword.Text) });

                        //After successful validation and password change, close the pop-up.
                        popupChangePassword.Close();

                        //Clock-In or Clock-Out the staff.
                        if (!clockOut)
                            ClockInCashier();
                        else
                            ClockOutCashier();
                    }
                    else
                    {
                        PivotalMessageBox.Show("Current Password verification failed. Please enter again.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtNewPassword.Text = string.Empty;
                        this.txtConfirmPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }
                }
                else
                {
                    //Verify the current password is correct and clock in the staff.
                    //User selects OK but value not provided.
                    if (txtCurrentPassword.Text.Trim() == string.Empty)
                    {
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }

                    string password = TypeConvert.ToString(Globals.ServerSqlIndex("RE_Staff", "Password_", Id.Create(loggedInCashier[0]["Staff_Id"])));
                    //Match the password with the DB value. If matched go ahead, esle prompt the user.
                    if (String.Equals(Globals.Decrypt(password), txtCurrentPassword.Text))
                    {
                        //After successful validation and password change, close the pop-up.
                        popupAuthorization.Close();
                    }
                    else
                    {
                        PivotalMessageBox.Show("Password verification failed. Please enter again.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        this.txtCurrentPassword.Text = string.Empty;
                        this.txtCurrentPassword.Focus();
                        return;
                    }
                    //Clock-In or Clock-Out the staff.
                    if (!clockOut)
                        ClockInCashier();
                    else
                        ClockOutCashier();
                }
            }
            catch (Exception ex)
            {
                Globals.HandleException(ex, true);
            }
        }

        /// <summary>
        /// Add a new row in the secondary staff login:
        ///•	Staff_Code = Staff Code entered above
        ///•	Staff_Id =  staff_Id retrieved above
        ///•	Store_Id =  current store
        ///•	Role =  Role selected above
        ///•	Login_Date =  Current Date
        ///•	In_Time = Current Time
        ///If the role is In Charge, update the In_Charge_Id field with the selected staff_id  for all the POS records for that store.
        ///Ensure that the staff id selected has the In_Charge flag set to true.
        ///Clear all the primary input fields.
        /// </summary>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.8.1        2011-09-06      DS              Initial version for Retail.                                                
        /// </history>
        private void ClockInCashier()
        {
            this.SystemClient.ExecuteServerTask("RE_Store", "ClockInCashier", new Type[] { typeof(string), typeof(object), typeof(object), typeof(object), typeof(object) },
                new object[] { loggedInCashier[0]["Staff_Code"].ToString(), loggedInCashier[0]["Staff_Id"], loggedInCashier[0]["Store_Id"], 
                    loggedInCashier[0]["POS_Id"], loggedInCashier[0]["Batch_Id"] });

            //Refresh the grid data.
            PivotalClientFormControl formControl = this.FormView.FormControl as PivotalClientFormControl;
            PivotalSearchResultsGrid cashierLoginGrid = (PivotalSearchResultsGrid)formControl.GetControlByName("CashierLoginGrid");
            cashierLoginGrid.RefreshGridData();

            //Clears all the primary fields.
            //ClearPrimaryFields();

            //Set the bottom status strip text.
            Globals.SetCashierStatusStrip(Globals.StatusStripPane.EnvironmentPane);

            this.FormView.CloseForm(true);
            //DS: 19042013 - For Offline if the POS is not master POS, then don't allow to create new Sale.
            if (SystemClient.SystemInformation.IsMobile && !Globals.IsMasterPOS)
                PivotalMessageBox.Show("New Sale is not available Offline when POS is not Master POS.", MessageBoxButtons.OK, MessageBoxIcon.Information);
            else
                Globals.ShowForm("RE_Sale – Walk In", null);            
        }

        /// <summary>
        /// Update the logged-in row in the secondary staff login:
        ///•	Out_Time = Current Time
        ///If the role is In Charge, update the In_Charge_Id field with the selected staff_id  for all the POS records for that store.
        ///Ensure that the staff id selected has the In_Charge flag set to true.
        ///Clear all the primary input fields.
        /// </summary>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.8.1        2011-09-06      DS              Initial version for Retail.                                                
        /// </history>
        private void ClockOutCashier()
        {
            this.SystemClient.ExecuteServerTask("RE_Store", "ClockOutCashier", new Type[] { typeof(Id), typeof(object), typeof(object) },
                new object[] { Id.Create(loggedInCashier[0]["RE_Cashier_Log_Id"]), loggedInCashier[0]["Store_Id"], loggedInCashier[0]["POS_Id"] });

            //Set the bottom status strip text.
            Globals.SetCashierStatusStrip(Globals.StatusStripPane.EnvironmentPane);
        }

        /// <summary>
        /// Show the Change password prompt..
        /// </summary>
        /// <history>
        /// Revision#      Date            Author          Description
        /// 6.0.8.1        2011-09-06      DS              Initial version for Retail.                                                
        /// </history>
        private void ShowChangePasswordPopup()
        {
            changePassword = true;
            popupChangePassword = new Form();

            this.txtCurrentPassword = new System.Windows.Forms.TextBox();
            this.txtNewPassword = new System.Windows.Forms.TextBox();
            this.txtConfirmPassword = new System.Windows.Forms.TextBox();
            this.btnOk = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.lblCurrentPassword = new System.Windows.Forms.Label();
            this.lblNewPassword = new System.Windows.Forms.Label();
            this.lblConfirmPassword = new System.Windows.Forms.Label();
            popupChangePassword.SuspendLayout();
            // 
            // txtCurrentPassword
            // 
            this.txtCurrentPassword.Location = new System.Drawing.Point(181, 30);
            this.txtCurrentPassword.Name = "txtCurrentPassword";
            this.txtCurrentPassword.Size = new System.Drawing.Size(109, 20);
            this.txtCurrentPassword.TabIndex = 0;
            this.txtCurrentPassword.UseSystemPasswordChar = true;
            // 
            // txtNewPassword
            // 
            this.txtNewPassword.Location = new System.Drawing.Point(181, 71);
            this.txtNewPassword.Name = "txtNewPassword";
            this.txtNewPassword.Size = new System.Drawing.Size(109, 20);
            this.txtNewPassword.TabIndex = 1;
            this.txtNewPassword.UseSystemPasswordChar = true;
            // 
            // txtConfirmPassword
            // 
            this.txtConfirmPassword.Location = new System.Drawing.Point(181, 112);
            this.txtConfirmPassword.Name = "txtNewPassword";
            this.txtConfirmPassword.Size = new System.Drawing.Size(109, 20);
            this.txtConfirmPassword.TabIndex = 2;
            this.txtConfirmPassword.UseSystemPasswordChar = true;
            // 
            // btnOk
            // 
            this.btnOk.Location = new System.Drawing.Point(134, 161);
            this.btnOk.Name = "Ok";
            this.btnOk.Size = new System.Drawing.Size(75, 23);
            this.btnOk.TabIndex = 3;
            this.btnOk.Text = "Ok";
            this.btnOk.BringToFront();
            this.btnOk.UseVisualStyleBackColor = true;
            this.btnOk.Click += new System.EventHandler(this.Ok_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.Location = new System.Drawing.Point(215, 161);
            this.btnCancel.Name = "Cancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 23);
            this.btnCancel.TabIndex = 4;
            this.btnCancel.Text = "Cancel";
            this.btnCancel.UseVisualStyleBackColor = true;
            // 
            // lblCurrentPassword
            // 
            this.lblCurrentPassword.AutoSize = true;
            this.lblCurrentPassword.Location = new System.Drawing.Point(43, 33);
            this.lblCurrentPassword.Name = "lblCurrentPassword";
            this.lblCurrentPassword.Size = new System.Drawing.Size(138, 15);
            this.lblCurrentPassword.TabIndex = 5;
            this.lblCurrentPassword.Text = "Current Password:";
            // 
            // lblNewPassword
            // 
            this.lblNewPassword.AutoSize = true;
            this.lblNewPassword.Location = new System.Drawing.Point(43, 74);
            this.lblNewPassword.Name = "lblNewPassword";
            this.lblNewPassword.Size = new System.Drawing.Size(138, 15);
            this.lblNewPassword.TabIndex = 5;
            this.lblNewPassword.Text = "New Password:";
            // 
            // lblConfirmPassword
            // 
            this.lblConfirmPassword.AutoSize = true;
            this.lblConfirmPassword.Location = new System.Drawing.Point(43, 115);
            this.lblConfirmPassword.Name = "lblConfirmPassword";
            this.lblConfirmPassword.Size = new System.Drawing.Size(138, 15);
            this.lblConfirmPassword.TabIndex = 6;
            this.lblConfirmPassword.Text = "Confirm Password:";
            // 
            // Form1
            // 
            popupChangePassword.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            popupChangePassword.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            popupChangePassword.AcceptButton = this.btnOk;
            popupChangePassword.CancelButton = this.btnCancel;
            popupChangePassword.ClientSize = new System.Drawing.Size(348, 224);
            popupChangePassword.StartPosition = FormStartPosition.CenterScreen;
            popupChangePassword.Controls.Add(this.lblCurrentPassword);
            popupChangePassword.Controls.Add(this.lblNewPassword);
            popupChangePassword.Controls.Add(this.lblConfirmPassword);
            popupChangePassword.Controls.Add(this.btnOk);
            popupChangePassword.Controls.Add(this.btnCancel);
            popupChangePassword.Controls.Add(this.txtCurrentPassword);
            popupChangePassword.Controls.Add(this.txtNewPassword);
            popupChangePassword.Controls.Add(this.txtConfirmPassword);
            popupChangePassword.Name = "popupChangePassword";
            popupChangePassword.Text = "Change Password";
            popupChangePassword.ResumeLayout(false);
            popupChangePassword.PerformLayout();
            popupChangePassword.ShowDialog();
        }
    }
}
